package com.weixin.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import com.weixin.config.WeiXinProperties;
import com.weixin.util.CSVUtils;
import com.weixin.util.CommonInputStreamResource;
import com.weixin.util.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.util.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.mock.web.MockMultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author zjd
 * @Title:
 * @Description:
 * @date 2021/4/1314:09
 */
@Api("企业微信通讯录-异步批量操作")
@RestController
@RequestMapping("/v1.0/wei-xin/cgi-bin/batch")
public class AsynchronousBatchController {
    @Autowired
    private RestTemplate restTemplate;
    @Resource
    private ObjectMapper objectMapper;

    @Autowired
    private RedisUtil redisUtil;

    @ApiOperation("下载全量成员与部门csv,type(1 成员 2部门 ) ")
    @GetMapping("/downloadFile")
    public ResponseEntity downloadFile(HttpServletResponse response, @RequestParam Integer type) throws IOException {
        ClassPathResource classPathResource = new ClassPathResource("static/batch_user_sample.csv");
        String fileName = type==1?"batch_user_sample.csv":"batch_party_sample.csv";
        CSVUtils.exportFile(response,classPathResource.getURL().getPath(),"batch_user_sample.csv");
        return new  ResponseEntity(HttpStatus.OK);

    }

    @ApiOperation("创建部门批量任务 ")
    @GetMapping("/createPartyJob")
    public ResponseEntity createPartyJob() throws Exception {
        getPartyFile();
        String s = uploadFile("static/batch_party_sample.csv");
        if (!StringUtils.isEmpty(s)){
            String job = partyJob(s,"replaceparty");
            return new  ResponseEntity(job,HttpStatus.OK);
        }
        return new  ResponseEntity(HttpStatus.OK);

    }

    @ApiOperation("创建成员批量任务 ")
    @GetMapping("/createUserJob")
    public ResponseEntity createUserJob() throws Exception {
        getUseryFile();
        String s = uploadFile("static/batch_user_sample.csv");
        if (!StringUtils.isEmpty(s)){
            String job = partyJob(s,"replaceuser");
            return new  ResponseEntity(job,HttpStatus.OK);
        }
        return new  ResponseEntity(HttpStatus.OK);

    }



    /**
     * 生成全量部门文件
     * */
    private void getPartyFile() throws IOException {
        ClassPathResource classPathResource = new ClassPathResource("static");
        String path = classPathResource.getURI().getPath();
        File f=new File(classPathResource.getURI().getPath());
        if (!f.exists()) {
            System.out.println(path+ " not exists");
            return;
        }else {
            File fa[] = f.listFiles();
            if(fa.length==0){
                return;
            }
            for (File  file: fa) {
                if (file.getName().equals("batch_party_sample.csv")){
                    file.delete();
                }
            }
        }

        List exportData = new ArrayList<Map>();
        Map row1 = new LinkedHashMap<String, String>();
        row1.put("name", "腾道");
        row1.put("id", "1");
        row1.put("parentid", "0");
        row1.put("order", "1");
        exportData.add(row1);
        row1 = new LinkedHashMap<String, String>();
        row1.put("name", "总办");
        row1.put("id", "2");
        row1.put("parentid", "1");
        row1.put("order", "1");
        exportData.add(row1);
        row1 = new LinkedHashMap<String, String>();
        row1.put("name", "微信事业群");
        row1.put("id", "3");
        row1.put("parentid", "1");
        row1.put("order", "2");
        exportData.add(row1);
        row1 = new LinkedHashMap<String, String>();
        row1.put("name", "产品部");
        row1.put("id", "4");
        row1.put("parentid", "3");
        row1.put("order", "1");
        exportData.add(row1);
        LinkedHashMap map = new LinkedHashMap();
        map.put("name", "部门名称");
        map.put("id", "部门ID");
        map.put("parentid", "父部门ID");
        map.put("order", "排序");

        File file = CSVUtils.createCSVFile(exportData, map, path, "batch_party_sample");
        String fileName2 = file.getName();
        System.out.println("文件名称：" + fileName2);
    }

    /**
     * 生成全量成员文件
     * */
    private void getUseryFile() throws IOException {
        ClassPathResource classPathResource = new ClassPathResource("static");
        String path = classPathResource.getURI().getPath();
        File f=new File(classPathResource.getURI().getPath());
        if (!f.exists()) {
            System.out.println(path+ " not exists");
            return;
        }else {
            File fa[] = f.listFiles();
            if(fa.length==0){
                return;
            }
            for (File  file: fa) {
                if (file.getName().equals("batch_user_sample.csv")){
                    file.delete();
                }
            }
        }

        List exportData = new ArrayList<Map>();
        Map row1 = new LinkedHashMap<String, String>();
        row1.put("name", "张三12");
        row1.put("id", "zhangsan1");
        row1.put("phone", "15913112120");
        row1.put("mailbox", "zhangsan@gzmailteam.com");
        row1.put("partyid", "1");
        row1.put("position", "产品经理1");
        row1.put("gender", "男");
        row1.put("lead", "1");
        row1.put("order", "10");
        row1.put("alias", "san zhang1");
        row1.put("address", "广州市");
        row1.put("landline", "020-1234");
        row1.put("disable", "0");
        row1.put("description", "");
        exportData.add(row1);
        row1 = new LinkedHashMap<String, String>();
        row1.put("name", "李四");
        row1.put("id", "lishi1");
        row1.put("phone", "18913112121");
        row1.put("mailbox", "lisi@gzmailteam.com");
        row1.put("partyid", "2");
        row1.put("position", "工程师");
        row1.put("gender", "女");
        row1.put("lead", "0");
        row1.put("order", "1000");
        row1.put("alias", "si li");
        row1.put("address", "");
        row1.put("landline", "");
        row1.put("disable", "0");
        row1.put("description", "");
        exportData.add(row1);
        row1 = new LinkedHashMap<String, String>();
        row1.put("name", "王五");
        row1.put("id", "wangwu");
        row1.put("phone", "13828282828");
        row1.put("mailbox", "wans@gzmailteam.com");
        row1.put("partyid", "2");
        row1.put("position", "测试工程师");
        row1.put("gender", "");
        row1.put("lead", "");
        row1.put("order", "");
        row1.put("alias", "w5s");
        row1.put("address", "");
        row1.put("landline", "");
        row1.put("disable", "0");
        row1.put("description", "");
        exportData.add(row1);
        row1 = new LinkedHashMap<String, String>();
        row1.put("name", "周俊东");
        row1.put("id", "ZhouJunDong");
        row1.put("phone", "15886370160");
        row1.put("mailbox", "zjd470@gzmailteam.com");
        row1.put("partyid", "1");
        row1.put("position", "");
        row1.put("gender", "");
        row1.put("lead", "");
        row1.put("order", "");
        row1.put("alias", "zjd");
        row1.put("address", "");
        row1.put("landline", "");
        row1.put("disable", "0");
        row1.put("description", "");
        exportData.add(row1);
        LinkedHashMap map = new LinkedHashMap();
        //姓名,帐号,手机号,邮箱,所在部门,职位,性别,是否部门内领导,排序,别名,地址,座机,禁用,禁用项说明：(0-启用;1-禁用)
        map.put("name", "姓名");
        map.put("id", "帐号");
        map.put("phone", "手机号");
        map.put("mailbox", "邮箱");
        map.put("partyid", "所在部门");
        map.put("position", "职位");
        map.put("gender", "性别");
        map.put("lead", "是否部门内领导");
        map.put("order", "排序");
        map.put("alias", "别名");
        map.put("address", "地址");
        map.put("landline", "座机");
        map.put("disable", "禁用");
        map.put("description", "禁用项说明");

        File file = CSVUtils.createCSVFile(exportData, map, path, "batch_user_sample");
        String fileName2 = file.getName();
        System.out.println("文件名称：" + fileName2);
    }

    /**
     * 上传文件
     * */
    public  String uploadFile( String re) throws Exception {
        ClassPathResource classPathResource = new ClassPathResource(re);

        File file1 = new File(classPathResource.getURI().getPath());

        FileInputStream inputStream = new FileInputStream(file1);
        MultipartFile upfile = new MockMultipartFile(file1.getName(), inputStream);

        StringBuilder urlBuilder=new StringBuilder(WeiXinProperties.getUrl());
        urlBuilder.append("cgi-bin/media/upload?");
        //String access_token =(String) session.getAttribute("access_token_application");
        String access_token = (String)redisUtil.get("access_token_application");
        urlBuilder.append("access_token="+access_token);
        urlBuilder.append("&type="+"file");
        // 构建请求头
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("appCode", "platform-device");
        requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
        // 构建请求体
        MultiValueMap<String, Object> requestBody = new LinkedMultiValueMap<>();
        // 获取文件名
        String fileName = upfile.getOriginalFilename();
        Assert.notNull(fileName,"获取上传的原始文件名不能为空");
        CommonInputStreamResource commonInputStreamResource = null;
        try  {
            commonInputStreamResource = new CommonInputStreamResource(upfile.getInputStream(),upfile.getSize(),upfile.getName());
        } catch (IOException e) {
            System.out.println("上传的文件转换异常" + e.getMessage());
        }
        requestBody.add("media", commonInputStreamResource);

        // 发送上传请求
        HttpEntity<MultiValueMap> requestEntity = new HttpEntity<MultiValueMap>(requestBody, requestHeaders);
        //ResponseEntity<HashMap> responseEntity = restTemplate.postForEntity("你的文件上传路径",requestEntity, HashMap.class);
        String result = restTemplate.postForObject(urlBuilder.toString(),requestEntity, String.class);
        Map<String, Object> readValue = objectMapper.readValue(result, HashMap.class);
        System.out.println(readValue);
        String mediaId = (String) readValue.get("media_id");
        return mediaId;
    }

    /**
     * 根据文件构建批量任务
     * */
    public String partyJob(String mediaId,String type) throws IOException {
        Map callback= new HashMap<String, Object>();
        callback.put("url","http://callback.tococn.com:9001/schedule/callback");
        callback.put("token","gB8OwG6NaP9tRVHhKWL3I");
        callback.put("encodingaeskey","rp0OvIjqTNln4zDEiTlPZJT2SP2ZRJIKxQ7lYF6jJ4P");
        Map map= new HashMap<String, Object>();
        map.put("media_id",mediaId);
        map.put("callback",callback);
        String jsonStr = objectMapper.writeValueAsString(map);
        StringBuilder urlBuilder=new StringBuilder(WeiXinProperties.getUrl());
        urlBuilder.append("cgi-bin/batch/"+type+"?");
        String access_token = (String) redisUtil.get("access_token_addressBook");
        urlBuilder.append("access_token="+access_token);
        HttpHeaders httpHeaders = new HttpHeaders();
        // 设置请求类型
        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
        // 封装参数和头信息
        HttpEntity<String> httpEntity = new HttpEntity<>(jsonStr, httpHeaders);
        String result = restTemplate.postForObject(urlBuilder.toString(),httpEntity, String.class);
        Map<String, Object> readValue = objectMapper.readValue(result, HashMap.class);
        System.out.println(readValue);
        String jobid =(String) readValue.get("jobid");
        return jobid;
    }

    /**
     * 将对象装换为map
     *
     * @param bean
     * @return
     */
    public static <T> Map<String, Object> beanToMap(T bean) {
        Map<String, Object> map = Maps.newHashMap();
        if (bean != null) {
            BeanMap beanMap = BeanMap.create(bean);
            for (Object key : beanMap.keySet()) {
                map.put(key + "", beanMap.get(key));
            }
        }
        return map;
    }

    public ResponseEntity<FileSystemResource> export() throws UnsupportedEncodingException {
        String url = ClassUtils.getDefaultClassLoader().getResource("").getPath();
        String path=url+"static/batch_user_sample.csv";
        File file=new File(path);
        if (file == null) {
            return null;
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        //headers.add("Content-Disposition", "attachment; filename=" + file.getName());
        headers.add("Content-Disposition", "attachment; filename=" + String.valueOf(URLEncoder.encode(file.getName(), "UTF-8")));
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("Last-Modified", new Date().toString());
        headers.add("ETag", String.valueOf(System.currentTimeMillis()));
        return ResponseEntity
                .ok()
                .headers(headers)
                .contentLength(file.length())
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(new FileSystemResource(file));
    }

    private ResponseEntity resultMap(Map<String, Object> resultMap, Integer type,String key){
        for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
            if (entry.getKey().equals("errcode")){
                Integer integer = (Integer) resultMap.get("errcode");
                if (integer==0){
                    ResponseEntity responseEntity = type==0 ? new ResponseEntity(resultMap.get(key), HttpStatus.OK): new ResponseEntity(resultMap, HttpStatus.OK);
                    return responseEntity;
                }
            }
        }
        return new ResponseEntity(resultMap,HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
